package com.wontube.core.dao.mybatis.provider;

import static org.apache.ibatis.jdbc.SqlBuilder.WHERE;

import java.util.List;

import com.wontube.core.dao.mybatis.Criteria;
import com.wontube.core.dao.mybatis.Criterion;
import com.wontube.core.dao.mybatis.QueryExample;


/**
 * @author yuechao
 * 
 */
public abstract class SqlProvider {
	protected void applyInCondition(String filedName, String condition) {
		String[] values = condition.split("[,]");
		StringBuilder sb = new StringBuilder(filedName + " in (");
		for (int index = 0; index < values.length; index++) {
			if (index > 0) {
				sb.append(",");
			}
			String value = values[index];
			sb.append("'" + value.trim().replace("'", "''") + "'");
		}
		sb.append(")");
		
		if (sb.length() > 0) {
			WHERE(sb.toString());
		}
	}
	
	protected void applyWhere(QueryExample example, boolean includeExamplePhrase) {
		if (example == null) {
			return;
		}

		String singleFormat;
		String singleTypeHandlerFormat;
		String betweenFormat;
		String betweenTypeHandlerFormat;
		String listFormat;
		String listTypeHandlerFormat;
		if (includeExamplePhrase) {
			singleFormat = "%s #{example.oredCriteria[%d].allCriteria[%d].value}";
			singleTypeHandlerFormat = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}";
			betweenFormat = "%s #{example.oredCriteria[%d].allCriteria[%d].value} and #{example.oredCriteria[%d].criteria[%d].secondValue}";
			betweenTypeHandlerFormat = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{example.oredCriteria[%d].criteria[%d].secondValue,typeHandler=%s}";
			listFormat = "#{example.oredCriteria[%d].allCriteria[%d].value[%d]}";
			listTypeHandlerFormat = "#{example.oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}";
		} else {
			singleFormat = "%s #{oredCriteria[%d].allCriteria[%d].value}";
			singleTypeHandlerFormat = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}";
			betweenFormat = "%s #{oredCriteria[%d].allCriteria[%d].value} and #{oredCriteria[%d].criteria[%d].secondValue}";
			betweenTypeHandlerFormat = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{oredCriteria[%d].criteria[%d].secondValue,typeHandler=%s}";
			listFormat = "#{oredCriteria[%d].allCriteria[%d].value[%d]}";
			listTypeHandlerFormat = "#{oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}";
		}

		StringBuilder sb = new StringBuilder();
		List<Criteria> oredCriteria = example.getOredCriteria();
		boolean firstCriteria = true;
		for (int i = 0; i < oredCriteria.size(); i++) {
			Criteria criteria = oredCriteria.get(i);
			if (criteria.isValid()) {
				if (firstCriteria) {
					firstCriteria = false;
				} else {
					sb.append(" or ");
				}

				sb.append('(');
				List<Criterion> criterions = criteria.getAllCriteria();
				boolean firstCriterion = true;
				for (int j = 0; j < criterions.size(); j++) {
					Criterion criterion = criterions.get(j);
					if (firstCriterion) {
						firstCriterion = false;
					} else {
						sb.append(" and ");
					}

					if (criterion.isNoValue()) {
						sb.append(criterion.getCondition());
					} else if (criterion.isSingleValue()) {
						if (criterion.getTypeHandler() == null) {
							sb.append(String.format(singleFormat, criterion.getCondition(), i, j));
						} else {
							sb.append(String.format(singleTypeHandlerFormat, criterion.getCondition(), i, j,
									criterion.getTypeHandler()));
						}
					} else if (criterion.isBetweenValue()) {
						if (criterion.getTypeHandler() == null) {
							sb.append(String.format(betweenFormat, criterion.getCondition(), i, j, i, j));
						} else {
							sb.append(String.format(betweenTypeHandlerFormat, criterion.getCondition(), i, j,
									criterion.getTypeHandler(), i, j, criterion.getTypeHandler()));
						}
					} else if (criterion.isListValue()) {
						sb.append(criterion.getCondition());
						sb.append(" (");
						List<?> listItems = (List<?>) criterion.getValue();
						boolean comma = false;
						for (int k = 0; k < listItems.size(); k++) {
							if (comma) {
								sb.append(", ");
							} else {
								comma = true;
							}
							if (criterion.getTypeHandler() == null) {
								sb.append(String.format(listFormat, i, j, k));
							} else {
								sb.append(String.format(listTypeHandlerFormat, i, j, k, criterion.getTypeHandler()));
							}
						}
						sb.append(')');
					}
				}
				sb.append(')');
			}
		}

		if (sb.length() > 0) {
			WHERE(sb.toString());
		}
	}
}
